package com.iflytek.jcy.supervise.job;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;

import org.apache.commons.collections.CollectionUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StopWatch;

import com.alibaba.fastjson.JSON;

@SpringBootApplication
@MapperScan("com.iflytek.jcy.supervise.job.mapper")
@EnableTransactionManagement
@EnableScheduling
@EnableAsync
public class Application {

	protected static final Logger logger = LoggerFactory.getLogger(Application.class);

	public static void main(String[] args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class).logStartupInfo(false)
		        // .banner(new AppBanner())
		        .run(args);
		stopWatch.stop();
		ServerProperties serverProperties = context.getBean(ServerProperties.class);
		Integer port = serverProperties.getPort();
		String contextPath = serverProperties.getServlet().getContextPath();
		String ip = Optional.ofNullable(getLocalAddress0()).map(InetAddress::getHostAddress).orElse("127.0.0.1");
		logger.info("{} 服务启动完成，耗时:{}s，swagger页面: http://{}:{}{}/doc.html", context.getId(), stopWatch.getTotalTimeSeconds(), ip, port, contextPath);
	}

	private static InetAddress getLocalAddress0() {
		InetAddress localAddress = null;
		try {
			localAddress = InetAddress.getLocalHost();
			if (isValidAddress(localAddress)) {
				return localAddress;
			}
		}
		catch (Throwable e) {
			//
		}
		try {
			Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
			List<NetworkInterface> list = convertAndSort(interfaces);
			logger.info("网卡地址列表是:{}", JSON.toJSONString(list));
			if (CollectionUtils.isNotEmpty(list)) {
				for (NetworkInterface network : list) {
					try {
						Enumeration<InetAddress> addresses = network.getInetAddresses();
						if (addresses != null) {
							while (addresses.hasMoreElements()) {
								try {
									InetAddress address = addresses.nextElement();
									if (isValidAddress(address)) {
										return address;
									}
								}
								catch (Throwable e) {
									//
								}
							}
						}
					}
					catch (Throwable e) {
						//
					}
				}
			}
		}
		catch (Throwable e) {
			//
		}
		return localAddress;
	}

	private static List<NetworkInterface> convertAndSort(Enumeration<NetworkInterface> interfaces) {
		List<NetworkInterface> list = new ArrayList<>();
		if (null == interfaces) {
			return list;
		}
		while (interfaces.hasMoreElements()) {
			NetworkInterface network = interfaces.nextElement();
			list.add(network);
		}
		// 按照网卡Index排序
		list.sort(Comparator.comparing(NetworkInterface::getIndex));
		return list;

	}

	private static boolean isValidAddress(InetAddress address) {
		Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
		if (address == null || address.isLoopbackAddress())
			return false;
		String name = address.getHostAddress();
		return (name != null && !"0.0.0.0".equals(name) && !"127.0.0.1".equals(name) && IP_PATTERN.matcher(name).matches());
	}
}